package com.imay.live.activity;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.View;
import android.view.ViewGroup;

import com.alibaba.fastjson.JSON;
import com.imay.cocos.IMayCocos;
import com.imay.live.activity.authentication.AuthenticationActivity;
import com.imay.live.analytics.MobclickAgent;
import com.imay.live.cache.UserInfoCache;
import com.imay.live.fragment.PopupMenuFragment;
import com.imay.live.fragment.room.BeautyFragment;
import com.imay.live.helper.DialogFragmentHelper;
import com.imay.live.helper.LocationHelper;
import com.imay.live.helper.PreferenceHelper;
import com.imay.live.helper.ThreadManager;
import com.imay.live.manager.AccountManager;
import com.imay.live.media.LivePlayer;
import com.imay.live.model.MenuItemModel;
import com.imay.live.model.UserInfoModel;
import com.imay.live.proto.ErrorResult;
import com.imay.live.proto.MessageId;
import com.imay.live.proto.ProtoResult;
import com.imay.live.proto.ResultCode;
import com.imay.live.proto.helper.ProtoCallBack;
import com.imay.live.proto.helper.ProtoRequestHelper;
import com.imay.live.proto.helper.ProtoSocketFactory;
import com.imay.live.proto.room.RoomCheckAdminResp;
import com.imay.live.proto.room.RoomLinkApplyListResp;
import com.imay.live.proto.room.RoomLinkConfirmNotify;
import com.imay.live.proto.user.UserInfoCard;
import com.imay.live.utils.AppUtil;
import com.imay.live.utils.ToastUtil;
import com.imay.live.view.custom.StartLiveView;
import com.imay.live.R;
import com.imay.tsnackbar.TSnackbar;

import java.util.ArrayList;

/**
 * Created by jeaman on 2017/3/17.
 */

public abstract class RoomPushBaseActivity extends RoomBaseActivity implements StartLiveView.OnActionClickListener, BeautyFragment.OnBeautyChangeListener, LocationHelper.OnLocationListener {
    private final static int MENU_ACTION_SET_ADMIN = 1;
    private final static int MENU_ACTION_REMOVE_ADMIN = 2;
    private final static int MENU_ACTION_ADMIN_LIST = 3;
    private final static int MENU_ACTION_LINK_LINE = 4;

    private final static int PERMISSION_REQUEST_CODE_LOCATION = 3;

    protected ViewGroup mContainerView;
    protected StartLiveView mStartLiveView;

    private ArrayList<MenuItemModel> mManagerMenuList = new ArrayList<>();
    private ArrayList<MenuItemModel> mManagerAdminMenuList = new ArrayList<>();

    protected boolean mShowLocation = true;   //是否开启定位
    protected String mCoverUrl;
    protected String mLastCoverUrl;
    protected String mCity;
    protected double mLatitude;
    protected double mLongitude;

    private boolean mWaitCheckLocalPermission;
    protected boolean mShowExitConfirm;

    @CallSuper
    @Override
    protected void initView(Bundle savedInstanceState) {
        mLiveVideoView = $(R.id.push_vv_video);
        mContainerView = $(R.id.push_rl_container);

        //mStartLiveView由子类动态创建
        mStartLiveView = createStartLiveView();
        mContainerView.addView(mStartLiveView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        //透明状态栏设置边距
        mStartLiveView.setPadding(0, getStatusBarHeight(), 0, 0);

        initPush(mLiveVideoView.getVideoView());

        registerNotify();
        initMenu();

        //需要post,否则容易出现黑屏无法显示摄像头画面
        mContainerView.post(new Runnable() {
            @Override
            public void run() {
                checkPermissionAndStartPreview();
            }
        });

        //检查定位权限
        mShowLocation = checkLocationPermission(false);
        setLocationStatus();
    }

    //是否是大主播
    protected boolean isMainPublisher() {
        return true;
    }

    @Override
    protected void onLiveBlock(long uid) {
        //封流、封房
        if (uid == AccountManager.getInstance().getUid()) {
            ToastUtil.show(this, R.string.tips_forbidden_account);
            requestEndLive();
        }
    }

    protected abstract StartLiveView createStartLiveView();
    protected abstract void requestStartLive();
    protected abstract void requestEndLive();
    protected abstract void onLocationSuccess();
    protected abstract void setLinkMicNumber(int number);

    private void initMenu() {
//        mManagerMenuList.add(new MenuItemModel(MENU_ACTION_LINK_LINE, R.string.live_menu_link_line));
        mManagerMenuList.add(new MenuItemModel(MENU_ACTION_SET_ADMIN, R.string.live_menu_set_admin));
        mManagerMenuList.add(new MenuItemModel(MENU_ACTION_ADMIN_LIST, R.string.live_menu_admin_list));
        mManagerMenuList.add(new MenuItemModel(MENU_ACTION_INFORM, R.string.live_menu_inform));
        mManagerMenuList.add(new MenuItemModel(MENU_ACTION_SILENCE, R.string.live_menu_silence));
        mManagerMenuList.add(new MenuItemModel(MENU_ACTION_KICK, R.string.live_menu_kick));

//        mManagerAdminMenuList.add(new MenuItemModel(MENU_ACTION_LINK_LINE, R.string.live_menu_link_line));
        mManagerAdminMenuList.add(new MenuItemModel(MENU_ACTION_REMOVE_ADMIN, R.string.live_menu_remove_admin));
        mManagerAdminMenuList.add(new MenuItemModel(MENU_ACTION_ADMIN_LIST, R.string.live_menu_admin_list));
        mManagerAdminMenuList.add(new MenuItemModel(MENU_ACTION_INFORM, R.string.live_menu_inform));
        mManagerAdminMenuList.add(new MenuItemModel(MENU_ACTION_SILENCE, R.string.live_menu_silence));
        mManagerAdminMenuList.add(new MenuItemModel(MENU_ACTION_KICK, R.string.live_menu_kick));
    }

    //需要实名认证
    protected void needRealNameAuth() {
        DialogFragmentHelper.showConfirmDialog(getSupportFragmentManager(), null, getString(R.string.live_real_name_auth), getString(R.string.button_auth), getString(R.string.str_dialog_choise_bottom), true, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AuthenticationActivity.startActivity(RoomPushBaseActivity.this);
                MobclickAgent.onEvent(RoomPushBaseActivity.this, "cdb_ready_go");
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MobclickAgent.onEvent(RoomPushBaseActivity.this, "cdb_ready_cancel");
            }
        });
    }

    protected void removeStartLiveView() {
        mContainerView.removeView(mStartLiveView);
        mStartLiveView = null;
    }

    protected void addRoomView() {
        addRoomView(-1);
    }

    protected void addRoomView(int index) {
        if (mRoomView != null && mRoomView.getParent() == null) {
            mContainerView.addView(mRoomView, index);
        }
    }

    protected void initRoomView() {
        super.initRoomView();
        mRoomView.setFollowUser(true);  //主播隐藏关注按钮
    }

    protected void setRoomAnchorInfo() {
        mRoomView.setAnchorInfo(mAnchorInfo);
    }

    //切换成大主播模式
    protected void changeToMainPublisherMode(String nick) {
        initPlayer(mLiveVideoView.getLinkMicVideoView());
        mLiveVideoView.showLinkMicView(isMainPublisher(), nick);
        mLivePusher.setMainPublisher();
        changeToLinkMicMode(nick);
    }

    //连麦邀请
    private void requestLinkMicInvite(long uid) {
        ProtoRequestHelper.task(ProtoSocketFactory.requestLinkMicInvite(uid)).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String command, String data) {
                ToastUtil.show(RoomPushBaseActivity.this, getString(R.string.link_mic_invite_success));
            }

            @Override
            public void onRequestError(String command, int code, String message) {
                ErrorResult.toastError(RoomPushBaseActivity.this, code);
            }
        });
    }

    //设置管理员
    private void requestSetAdmin(long uid) {
        ProtoRequestHelper.task(ProtoSocketFactory.requestSetAdmin(mRoomId, uid)).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String command, String data) {
                ToastUtil.show(RoomPushBaseActivity.this, R.string.tips_success_set_admin);
            }

            @Override
            public void onRequestError(String command, int code, String message) {
                ErrorResult.toastError(RoomPushBaseActivity.this, code);
            }
        });
    }

    //删除管理员
    private void requestRemoveAdmin(long uid) {
        ProtoRequestHelper.task(ProtoSocketFactory.requestRemoveAdmin(mRoomId, uid)).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String command, String data) {
                ToastUtil.show(RoomPushBaseActivity.this, R.string.tips_success_remove_admin);
            }

            @Override
            public void onRequestError(String command, int code, String message) {
                ErrorResult.toastError(RoomPushBaseActivity.this, code);
            }
        });
    }

    private void showLocationPermissionDialog(String title, String message) {
        DialogFragmentHelper.showConfirmDialog(getSupportFragmentManager(), title, message,
                getString(R.string.permission_button_setting), null, false, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //activity恢复后是否再次检查权限
                        mWaitCheckLocalPermission = true;
                        AppUtil.startInstalledAppDetailsActivity(RoomPushBaseActivity.this);
                    }
                }, null);
    }

    //显示开启定位状态
    private void setLocationStatus() {
        //TODO 需要优化开启定位的流程
        if (mShowLocation) {
            getLocation();
        }
        mStartLiveView.setLocationStatus(mShowLocation);
    }

    //检查定位权限，并获取定位
    private boolean checkLocationPermission(boolean showDialog) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if (showDialog) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
                        || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
                    showLocationPermissionDialog(getString(R.string.permission_location_title), getString(R.string.permission_location));
                } else {
                    // 请求权限
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE_LOCATION);
                }
            }
            return false;
        } else {
            return true;
        }
    }

    private void getLocation() {
        LocationHelper.getInstance().getLocation(this);
    }

    protected void showGame() {
        IMayCocos.showGamePanel();
    }

    //处理自己类业务的消息
    @Override
    protected void processSocketNotify(int msgId, String content) {
        switch (msgId) {
            case MessageId.roomLinkApplyNotify: //连麦通知
                final RoomLinkApplyListResp roomLinkApplyListResp = JSON.parseObject(content, RoomLinkApplyListResp.class);
                ThreadManager.post(new Runnable() {
                    @Override
                    public void run() {
                        if (getRoomId() == roomLinkApplyListResp.roomId && mRoomView != null) {
                            setLinkMicNumber(roomLinkApplyListResp.users == null ? 0 : roomLinkApplyListResp.users.size());
                        }
                    }
                });
                break;
            case MessageId.roomLinkConfirmNotify:   //观众接受连麦通知
                final RoomLinkConfirmNotify roomLinkConfirmNotify = JSON.parseObject(content, RoomLinkConfirmNotify.class);
                ThreadManager.post(new Runnable() {
                    @Override
                    public void run() {
//                        if (getRoomId() == roomLinkConfirmNotify.roomId) {
                        if (!roomLinkConfirmNotify.deny) {   //同意连麦
                            mLinkMicStreamUrl = roomLinkConfirmNotify.pullStreamUrl;
                            changeToMainPublisherMode(roomLinkConfirmNotify.user == null ? null : roomLinkConfirmNotify.user.nick);
                        } else {    //拒绝连麦
                            DialogFragmentHelper.showTipsDialog(getSupportFragmentManager(), getString(R.string.link_mic_refuse_tips));
                        }
//                        }
                    }
                });
                break;
        }
    }

    @Override
    public LivePlayer getLivePlayer() {
        return mLivePlayer;
    }

    public void onResume() {
        super.onResume();
        //重新检查定位权限
        if (mWaitCheckLocalPermission) {
            mWaitCheckLocalPermission = false;
            mShowLocation = checkLocationPermission(false);
            setLocationStatus();
        }
    }

    @Override
    protected String getCoverUrl() {
        if (mCoverUrl != null) {
            return mCoverUrl;
        } else if (mLastCoverUrl != null) {
            return mLastCoverUrl;
        } else {
            UserInfoModel user = UserInfoCache.getUserInfo();
            if (user != null) {
                return user.getUser().getImgHead();
            }
        }
        return null;
    }

    @Override
    public void onBeautyChange(int beautyLevel, int whiteningLevel, int ruddyLevel) {
        PreferenceHelper.getInstance().saveBeautyLevel(beautyLevel);
        PreferenceHelper.getInstance().saveWhiteningLevel(whiteningLevel);
        PreferenceHelper.getInstance().saveRuddyLevel(ruddyLevel);
        mLivePusher.setBeautyFilter(beautyLevel, whiteningLevel, ruddyLevel);
    }

    @Override
    public void onBeautyDismiss() {
        if (mRoomView != null) {
            mRoomView.onHideBeautyView();
        }
        if (mStartLiveView != null) {
            mStartLiveView.onHideBeautyView();
        }
    }

    @Override
    public void onLocationClick() {
        mShowLocation = !mShowLocation;
        if (mShowLocation) {
            //检查定位权限并且没有权限弹出提示框
            mShowLocation = checkLocationPermission(true);
        }
        setLocationStatus();
    }

    @Override
    public void onCameraClick() {
        switchCamera();
    }

    protected void showBeautyView() {
        if (mStartLiveView != null) {
            mStartLiveView.onShowBeautyView();
        }
//        if (mRoomView != null) {
//            mRoomView.onShowBeautyView();
//        }
        DialogFragmentHelper.showDialogFragment(getSupportFragmentManager(), BeautyFragment.newInstance(mLivePusher.getBeautyLevel(), mLivePusher.getWhiteningLevel(), mLivePusher.getRuddyLevel()));

    }

    @Override
    public void onBeautyClick() {
        showBeautyView();
    }

    @Override
    public void onStartClick() {
        requestStartLive();
    }

    @Override
    public void showAdminMenu(final UserInfoCard userInfoCard) {
        //显示管理菜单
        DialogFragmentHelper.showDialogFragment(getSupportFragmentManager(), PopupMenuFragment.newInstance(mManagerMenuList), FRAGMENT_TAG_MANAGER_MENU);
        //判断是否管理员
        ProtoRequestHelper.task(ProtoSocketFactory.requestCheckAdmin(getRoomId(), userInfoCard.uid)).setTag(this.hashCode()).request(new ProtoCallBack() {
            @Override
            public void onRequestSuccess(String command, String data) {
                Fragment fragment = DialogFragmentHelper.getFragment(getSupportFragmentManager(), FRAGMENT_TAG_MANAGER_MENU);
                if (fragment instanceof PopupMenuFragment) {
                    PopupMenuFragment popupMenuFragment = (PopupMenuFragment) fragment;
                    RoomCheckAdminResp resp = JSON.parseObject(data, RoomCheckAdminResp.class);
                    if (resp.result == ResultCode.CodeSuccess) {
                        if (resp.isAdmin && mMenuActionUser == userInfoCard) {
                            popupMenuFragment.setNewMenu(mManagerAdminMenuList);
                        }
                    }
                }
            }

            @Override
            public void onRequestError(String command, int code, String message) {

            }
        });
    }

    @Override
    public void processPopupMenuClick(int action) {
        switch (action) {
            case MENU_ACTION_LINK_LINE: //主播连线
                DialogFragmentHelper.showConfirmDialog(getSupportFragmentManager(), getString(R.string.confirm_link_mic, mMenuActionUser.nick), new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        requestLinkMicInvite(mMenuActionUser.uid);
                    }
                });
                break;
            case MENU_ACTION_SET_ADMIN: //设置管理员
                DialogFragmentHelper.showConfirmDialog(getSupportFragmentManager(), getString(R.string.confirm_set_admin, mMenuActionUser.nick), new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        requestSetAdmin(mMenuActionUser.uid);
                    }
                });
                break;
            case MENU_ACTION_REMOVE_ADMIN:  //删除管理员
                DialogFragmentHelper.showConfirmDialog(getSupportFragmentManager(), null, getString(R.string.confirm_remove_admin, mMenuActionUser.nick), new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        requestRemoveAdmin(mMenuActionUser.uid);
                    }
                });
                break;
            case MENU_ACTION_ADMIN_LIST:    //管理员列表
                RoomAdminActivity.startActivity(this, mRoomId);
                break;
            default:
                super.processPopupMenuClick(action);
        }
    }

    //定位成功
    @Override
    public void onLocation(String city, double latitude, double longitude) {
        mCity = city;
        mLatitude = latitude;
        mLongitude = longitude;
        onLocationSuccess();
    }

    @Override
    public void onPushNetBusy() {
        TSnackbar.make(getDecorView(), getString(R.string.tip_network_busy)).show();
        ProtoRequestHelper.task(ProtoSocketFactory.requestSetLiveBusy()).request(null);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CODE_LOCATION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 用户允许，开启定位
                    mShowLocation = true;
                    setLocationStatus();
                }
                break;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}
